package com.darren.framework.interceptor;

import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.darren.framework.entity.AppSession;
import com.darren.framework.entity.LoginRecord;
import com.darren.framework.entity.LoginRecord.LoginType;
import com.darren.framework.entity.TokenEntity;
import com.darren.framework.entity.User;
import com.darren.framework.service.LoginRecordService;
import com.darren.framework.service.UserService;
import com.darren.framework.utils.JWTUtil;
import com.darren.framework.utils.JWTUtil.TokenStatus;
import com.darren.framework.utils.StringUtil;




public class UserTokenInterceptor  implements HandlerInterceptor {
	
	private static final Log log = LogFactory.getLog(UserTokenInterceptor.class);	
	
	@Resource
	private LoginRecordService loginRecordService;
	
	@Autowired
    private UserService userService;
	
	private List<String> excludes;

	public List<String> getExcludes() {
		return excludes;
	}

	public void setExcludes(List<String> excludes) {
		this.excludes = excludes;
	}

	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object obj, Exception arg3)
			throws Exception {

	}

	public void postHandle(HttpServletRequest request, HttpServletResponse response,
			Object arg2, ModelAndView modelAndView) {
		if(!StringUtil.isEmpty(modelAndView)){
			System.out.println("****************************************************************************************************");
			System.out.println("========= Redirect Path (Next View):========= "+ modelAndView.getViewName());
			System.out.println("****************************************************************************************************");
		}
		AppSession appSession = (AppSession) request.getAttribute("appSession");
		if(appSession != null && appSession.isUpdated()){
			LoginRecord loginRecord = (LoginRecord) request.getAttribute("loginRecord");
			try {
				loginRecord.setApplicationSession(appSession);
				loginRecordService.update(loginRecord);
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		}
		request.removeAttribute("user");
		request.removeAttribute("appSession");
		request.removeAttribute("loginRecord");
	}

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object obj){
		String requestUri = request.getRequestURI();
		String projectName = request.getContextPath();
		//放行exceptUrls中配置的url
		for (String url : excludes) {
			if(url.endsWith("/**")){
				if (requestUri.startsWith(url.substring(0, url.length() - 3))) {
					return true;
				}
			} else if (requestUri.startsWith(url) || requestUri.startsWith(projectName+url)) {
				return true;
			}
		}
		String accessToken = request.getHeader("accessToken");
		log.info(String.format("accessToken:%s;", accessToken));
		JSONObject responseJson = new JSONObject();
		JSONObject tokenJson = JWTUtil.unsignAccessJWT(accessToken, TokenEntity.class);
		TokenStatus tokenStatus = (TokenStatus) tokenJson.get("status");		
		if(tokenStatus != TokenStatus.AVILIBLE){
			responseJson.put("status", tokenStatus.getCode());
			responseJson.put("message",tokenStatus.getMessage());			
			return ajax(responseJson.toString(),response);
		}
		log.info(String.format("payload:%s", tokenJson.get("payload")));
		TokenEntity token = (TokenEntity) tokenJson.get("payload");		
		LoginRecord loginRecord = loginRecordService.findById(token.getId());
		if(loginRecord == null){
			responseJson.put("status", -10001);
			responseJson.put("message", "session失效，请重新登陆。");			
			return ajax(responseJson.toString(),response);
		}
		if(!LoginType.USER.getDescription().equals(loginRecord.getLoginType())){
			responseJson.put("status", -10002);
			responseJson.put("message", "非法请求。");			
			return ajax(responseJson.toString(),response);
		}
		User user = userService.findById(loginRecord.getLoginId());
		if(user != null){
			responseJson.put("status", -10003);
			responseJson.put("message", "用户不存在，或者已被删除。");			
			return ajax(responseJson.toString(),response);
		}
		request.setAttribute("user", user);
		AppSession appSession = null;
		try {
			appSession = loginRecord.getApplicationSession();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		if(!accessToken.equals(appSession.getAttribute("accessToken"))){
			responseJson.put("status", -10004);
			responseJson.put("message", "token 已废弃。");			
			return ajax(responseJson.toString(),response);
		}
		appSession.resetUpdated();
		response.setHeader("accessToken", accessToken);
		request.setAttribute("appSession", appSession);
		request.setAttribute("loginRecord", loginRecord);
		return true;
	}
	
	private boolean ajax(String content,HttpServletResponse response) {
		try {
			response.setContentType("text/html" + ";charset=UTF-8");		
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			response.getWriter().write(content);
			response.getWriter().flush();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return false;
	}

}
